package com.jyw.router.miniapp.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import com.jyw.router.common.annotation.Anonymous;
import com.jyw.router.common.core.domain.CommonResult;
import com.jyw.router.common.exception.ServiceException;
import com.jyw.router.common.exception.constant.ExceptionCodeConstant;
import com.jyw.router.common.utils.JsonUtils;
import com.jyw.router.hospital.domain.WxUser;
import com.jyw.router.hospital.service.IWxUserService;
import com.jyw.router.hospital.domain.vo.LoginMiniappVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 * 微信小程序用户接口
 *
 * @author <a href="https://github.com/binarywang">Binary Wang</a>
 */
@RestController
@AllArgsConstructor
@Slf4j
@RequestMapping("/wx/miniapp/user")
@Api(tags = "微信小程序用户接口")
public class WxMaUserController {
    private final WxMaService wxMaService;

    @Resource
    private final IWxUserService wxUserService;

    @PostMapping("/login")
    @ApiOperation("登录小程序")
    @Anonymous
    public CommonResult login(@RequestBody LoginMiniappVo loginVo){
        //判断是否传入唯一标识
        if(!StringUtils.isBlank(loginVo.getOpenId())){
            WxUser wxUser = wxUserService.getUserByMiniappOpenId(loginVo.getOpenId());
            if(ObjectUtils.isEmpty(wxUser)){
                throw new ServiceException("小程序唯一标识异常,系统中不存在该用户");
            }
            loginVo.setPhone(wxUser.getPhone());
            loginVo.setUnionId(wxUser.getUnionId());
        }else{
            //获取唯一标识
            try {
                WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(loginVo.getCode());
                //设置唯一标识
                loginVo.setOpenId(session.getOpenid());
                loginVo.setUnionId(session.getUnionid());
                //查询数据库中的用户信息,写入手机号,避免重新写入
                WxUser wxUser = wxUserService.getUserByMiniappOpenId(loginVo.getOpenId());
                if(!ObjectUtils.isEmpty(wxUser)){
                    if(StringUtils.isEmpty(wxUser.getPhone())&&!StringUtils.isEmpty(loginVo.getPhone())){
                        wxUser = wxUserService.registerMiniApp(loginVo);
                    }
                    loginVo.setPhone(wxUser.getPhone());
                }


                //用户未注册,并且未走无码报修
                if(StringUtils.isEmpty(loginVo.getHospitalId())
                        &&
                        StringUtils.isEmpty(loginVo.getPhone())){
                    //如果没有在系统中注册,并且没有提供手机号,那么返回绑定异常
                    throw new ServiceException("请绑定手机号", ExceptionCodeConstant.NOT_BIND_PHONE);
                }

            } catch (WxErrorException e) {
                log.error("调用小程序API获取用户Session错误",e);
                throw new ServiceException("调用微信API获取,用户信息错误,登录失败");
            }
        }

        //登录账号
        return wxUserService.login(loginVo);
    }

    /**
     * 登陆接口
     */
    @GetMapping("/login")
    public String login( String code) {
        if (StringUtils.isBlank(code)) {
            return "empty jscode";
        }

        try {
            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code);
            log.info(session.getSessionKey());
            log.info(session.getOpenid());
            //TODO 可以增加自己的逻辑，关联业务相关数据
            return JsonUtils.toJson(session);
        } catch (WxErrorException e) {
            log.error(e.getMessage(), e);
            return e.toString();
        } finally {
            WxMaConfigHolder.remove();//清理ThreadLocal
        }
    }

    /**
     * <pre>
     * 获取用户信息接口
     * </pre>
     */
    @GetMapping("/info")
    public String info( String sessionKey,
                       String signature, String rawData, String encryptedData, String iv) {

        // 用户信息校验
        if (!wxMaService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            WxMaConfigHolder.remove();//清理ThreadLocal
            return "user check failed";
        }

        // 解密用户信息
        WxMaUserInfo userInfo = wxMaService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
        WxMaConfigHolder.remove();//清理ThreadLocal
        return JsonUtils.toJson(userInfo);
    }

    /**
     * <pre>
     * 获取用户绑定手机号信息
     * </pre>
     */
    @GetMapping("/phone")
    @ApiOperation("获取用户绑定的手机号信息")
    @Anonymous
    public CommonResult<String> phone(String code) {
        // 解密
        WxMaPhoneNumberInfo phoneNoInfo = null;
        try {
            phoneNoInfo = wxMaService.getUserService().getNewPhoneNoInfo(code);
        } catch (WxErrorException e) {
            log.error("获取用户手机号异常",e);
            throw new ServiceException("获取手机号异常");
        }
        WxMaConfigHolder.remove();//清理ThreadLocal
        return CommonResult.success(null,phoneNoInfo.getPhoneNumber());
    }

}
